/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

using System;
using System.Collections.Generic;

namespace FaceCat {
    /// <summary>
    /// 滚动条视图
    /// </summary>
    public class FCScrollBar : FCView, FCEventCallBack, FCTouchEventCallBack {
        /// <summary>
        /// 创建滚动条
        /// </summary>
        public FCScrollBar() {
            setDisplayOffset(false);
            m_size = new FCSize(10, 10);
            setTopMost(true);
        }

        public int m_addSpeed;

        /// <summary>
        /// 获取当前的加速度
        /// </summary>
        public virtual int getAddSpeed() {
            return m_addSpeed;
        }

        /// <summary>
        /// 设置当前的加速度
        /// </summary>
        public virtual void setAddSpeed(int addSpeed) {
            m_addSpeed = addSpeed;
            if (m_addSpeed != 0) {
                startTimer(m_timerID, 10);
            } else {
                stopTimer(m_timerID);
            }
        }

        public bool m_isAdding;

        /// <summary>
        /// 获取是否正在增量
        /// </summary>
        public virtual bool isAdding() {
            return m_isAdding;
        }

        /// <summary>
        /// 设置是否正在增量
        /// </summary>
        public virtual void setIsAdding(bool value) {
            if (m_isAdding != value) {
                m_isAdding = value;
                m_tick = 0;
                if (m_isAdding) {
                    startTimer(m_timerID, 100);
                } else {
                    stopTimer(m_timerID);
                }
            }
        }

        public bool m_isReducing;

        /// <summary>
        /// 获取是否正在减量
        /// </summary>
        public virtual bool isReducing() {
            return m_isReducing;
        }

        /// <summary>
        /// 设置是否正在减量
        /// </summary>
        public virtual void setIsReducing(bool value) {
            if (m_isReducing != value) {
                m_isReducing = value;
                m_tick = 0;
                if (m_isReducing) {
                    startTimer(m_timerID, 100);
                } else {
                    stopTimer(m_timerID);
                }
            }
        }

        /// <summary>
        /// 秒表计数
        /// </summary>
        private int m_tick;

        /// <summary>
        /// 秒表ID
        /// </summary>
        private int m_timerID = getNewTimerID();

        public FCButton m_addButton;

        /// <summary>
        /// 增量按钮
        /// </summary>
        public virtual FCButton getAddButton() {
            return m_addButton;
        }

        public FCButton m_backButton;

        /// <summary>
        /// 获取滚动背景按钮
        /// </summary>
        public virtual FCButton getBackButton() {
            return m_backButton;
        }

        public int m_contentSize = 0;

        /// <summary>
        /// 获取内容尺寸
        /// </summary>
        public virtual int getContentSize() {
            return m_contentSize;
        }

        /// <summary>
        /// 设置内容尺寸
        /// </summary>
        public virtual void setContentSize(int value) {
            m_contentSize = value;
        }

        public int m_lineSize = 10;

        /// <summary>
        /// 获取每次滚动的行尺寸
        /// </summary>
        public virtual int getLineSize() {
            return m_lineSize;
        }

        /// <summary>
        /// 设置每次滚动的行尺寸
        /// </summary>
        public virtual void setLineSize(int value) {
            m_lineSize = value;
        }

        public int m_pageSize;

        /// <summary>
        /// 获取页的尺寸
        /// </summary>
        public virtual int getPageSize() {
            return m_pageSize;
        }

        /// <summary>
        /// 设置页的尺寸
        /// </summary>
        public virtual void setPageSize(int value) {
            m_pageSize = value;
        }

        public int m_pos;

        /// <summary>
        /// 获取滚动距离
        /// </summary>
        public virtual int getPos() {
            return m_pos;
        }

        /// <summary>
        /// 设置滚动距离
        /// </summary>
        public virtual void setPos(int value) {
            m_pos = value;
            if (m_pos > m_contentSize - m_pageSize) {
                m_pos = m_contentSize - m_pageSize;
            }
            if (m_pos < 0) {
                m_pos = 0;
            }
        }

        public FCButton m_reduceButton;

        /// <summary>
        /// 减量按钮
        /// </summary>
        public virtual FCButton getReduceButton() {
            return m_reduceButton;
        }

        public FCButton m_scrollButton;

        /// <summary>
        /// 获取滚动按钮
        /// </summary>
        public virtual FCButton getScrollButton() {
            return m_scrollButton;
        }

        /// <summary>
        /// 事件回调
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="invoke"></param>
        public virtual void callEvent(String eventName, Object sender, Object invoke) {
            if (sender == m_scrollButton) {
                if (eventName == "ondragging") {
                    onDragScroll();
                }
            }
        }

        /// <summary>
        /// 触摸事件回调
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="sender"></param>
        /// <param name="touchInfo"></param>
        /// <param name="invoke"></param>
        public virtual void callTouchEvent(String eventName, Object sender, FCTouchInfo touchInfo, Object invoke) {
            if (sender == m_addButton) {
                if (eventName == "ontouchdown") {
                    onAddButtonTouchDown(touchInfo.clone());
                } else if (eventName == "ontouchup") {
                    onAddButtonTouchUp(touchInfo.clone());
                }
            } else if (sender == m_reduceButton) {
                if (eventName == "ontouchdown") {
                    onReduceButtonTouchDown(touchInfo.clone());
                } else if (eventName == "ontouchup") {
                    onReduceButtonTouchUp(touchInfo.clone());
                }
            }
        }

        /// <summary>
        /// 销毁方法
        /// </summary>
        public override void delete() {
            if (!isDeleted()) {
                stopTimer(m_timerID);
                if (m_addButton != null) {
                    m_addButton.removeEvent(this, "ontouchdown");
                    m_addButton.removeEvent(this, "ontouchup");
                }
                if (m_scrollButton != null) {
                    m_scrollButton.removeEvent(this, "ondragging");
                }
                if (m_reduceButton != null) {
                    m_reduceButton.removeEvent(this, "ontouchdown");
                    m_reduceButton.removeEvent(this, "ontouchup");
                }
            }
            base.delete();
        }

        /// <summary>
        /// 获取视图类型
        /// </summary>
        /// <returns>视图类型</returns>
        public override String getViewType() {
            return "ScrollBar";
        }

        /// <summary>
        /// 获取事件名称列表
        /// </summary>
        /// <returns>名称列表</returns>
        public override ArrayList<String> getEventNames() {
            ArrayList<String> eventNames = base.getEventNames();
            eventNames.AddRange(new String[] { "Scrolled" });
            return eventNames;
        }

        /// <summary>
        /// 行变大方法
        /// </summary>
        public virtual void lineAdd() {
            m_pos += m_lineSize;
            if (m_pos > m_contentSize - m_pageSize) {
                m_pos = m_contentSize - m_pageSize;
            }
            update();
            onScrolled();
        }

        /// <summary>
        /// 行变小方法
        /// </summary>
        public virtual void lineReduce() {
            m_pos -= m_lineSize;
            if (m_pos < 0) {
                m_pos = 0;
            }
            update();
            onScrolled();
        }

        /// <summary>
        /// 增量滚动按钮按下事件方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public void onAddButtonTouchDown(FCTouchInfo touchInfo) {
            lineAdd();
            setIsAdding(true);
        }

        /// <summary>
        /// 增量滚动按钮抬起事件方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public void onAddButtonTouchUp(FCTouchInfo touchInfo) {
            setIsAdding(false);
        }

        /// <summary>
        /// 加速滚动结束
        /// </summary>
        public virtual void onAddSpeedScrollEnd() {
        }

        /// <summary>
        /// 自动加速滚动开始
        /// </summary>
        public virtual void onAddSpeedScrollStart(long startTime, long nowTime, int start, int end) {
            int diff = (int)((nowTime - startTime) / 10000);
            if (diff > 0 && diff < 500) {
                int sub = 5000 * (Math.Abs(start - end) / 20) / diff;
                if (start > end) {
                    setAddSpeed(getAddSpeed() + sub);
                }
                else if (start < end) {
                    setAddSpeed(getAddSpeed() - sub);
                }
            }
        }

        /// <summary>
        /// 自动加速滚动中
        /// </summary>
        public virtual int onAddSpeedScrolling() {
            int sub = m_addSpeed / 10;
            if (sub == 0) {
                sub = m_addSpeed > 0 ? 1 : -1;
            }
            return sub;
        }

        /// <summary>
        /// 拖动滚动方法
        /// </summary>
        public virtual void onDragScroll() {
            if (m_scrollButton.getLeft() < 0) {
                m_scrollButton.setLeft(0);
            }
            if (m_scrollButton.getTop() < 0) {
                m_scrollButton.setTop(0);
            }
            if (m_scrollButton.getRight() > m_backButton.getWidth()) {
                m_scrollButton.setLeft(m_backButton.getWidth() - m_scrollButton.getWidth());
            }
            if (m_scrollButton.getBottom() > m_backButton.getHeight()) {
                m_scrollButton.setTop(m_backButton.getHeight() - m_scrollButton.getHeight());
            }
        }

        /// <summary>
        /// 视图添加方法
        /// </summary>
        public override void onLoad() {
            base.onLoad();
            //添加按钮
            FCHost host = getNative().getHost();
            if (m_addButton == null) {
                m_addButton = host.createInternalView(this, "addbutton") as FCButton;
                m_addButton.addEvent(this, "ontouchdown", null);
                m_addButton.addEvent(this, "ontouchup", null);
                addView(m_addButton);
            }
            if (m_backButton == null) {
                m_backButton = host.createInternalView(this, "backbutton") as FCButton;
                addView(m_backButton);
            }
            if (m_reduceButton == null) {
                m_reduceButton = host.createInternalView(this, "reducebutton") as FCButton;
                m_reduceButton.addEvent(this, "ontouchdown", null);
                m_reduceButton.addEvent(this, "ontouchup", null);
                addView(m_reduceButton);
            }
            if (m_scrollButton == null) {
                m_scrollButton = host.createInternalView(this, "scrollbutton") as FCButton;
                m_scrollButton.setAllowDrag(true);
                m_scrollButton.addEvent(this, "ondragging", null);
                m_backButton.addView(m_scrollButton);
            }
        }

        /// <summary>
        /// 减量滚动按钮按下事件方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public void onReduceButtonTouchDown(FCTouchInfo touchInfo) {
            lineReduce();
            setIsReducing(true);
        }

        /// <summary>
        /// 减量滚动按钮抬起事件回调方法
        /// </summary>
        /// <param name="touchInfo">触摸信息</param>
        public void onReduceButtonTouchUp(FCTouchInfo touchInfo) {
            setIsReducing(false);
        }

        /// <summary>
        /// 滚动时触发
        /// </summary>
        public virtual void onScrolled() {
            callEvents("onscrolled");
            FCView parent = getParent();
            if (parent != null) {
                parent.invalidate();
            }
        }

        /// <summary>
        /// 秒表回调方法
        /// </summary>
        /// <param name="timerID">秒表ID</param>
        public override void onTimer(int timerID) {
            base.onTimer(timerID);
            if (m_timerID == timerID) {
                if (m_isAdding) {
                    if (m_tick > 5) {
                        pageAdd();
                    }
                    else {
                        lineAdd();
                    }
                }
                if (m_isReducing) {
                    if (m_tick > 5) {
                        pageReduce();
                    }
                    else {
                        lineReduce();
                    }
                }
                if (m_addSpeed != 0) {
                    int sub = onAddSpeedScrolling();
                    setPos(getPos() + sub);
                    update();
                    onScrolled();
                    m_addSpeed -= sub;
                    if (Math.Abs(m_addSpeed) < 3) {
                        m_addSpeed = 0;
                    }
                    if (m_addSpeed == 0) {
                        onAddSpeedScrollEnd();
                        stopTimer(m_timerID);
                        if (getParent() != null) {
                            getParent().invalidate();
                        }
                    }
                }
                m_tick++;
            }
        }

        /// <summary>
        /// 可见状态改变方法
        /// </summary>
        public override void onVisibleChanged() {
            base.onVisibleChanged();
            if (!isVisible()) {
                m_pos = 0;
            }
        }

        /// <summary>
        /// 页变大方法
        /// </summary>
        public virtual void pageAdd() {
            m_pos += m_pageSize;
            if (m_pos > m_contentSize - m_pageSize) {
                m_pos = m_contentSize - m_pageSize;
            }
            update();
            onScrolled();
        }

        /// <summary>
        /// 页变小方法
        /// </summary>
        public virtual void pageReduce() {
            m_pos -= m_pageSize;
            if (m_pos < 0) {
                m_pos = 0;
            }
            update();
            onScrolled();
        }

        /// <summary>
        /// 滚动到开始
        /// </summary>
        public virtual void scrollToBegin() {
            m_pos = 0;
            update();
            onScrolled();
        }

        /// <summary>
        /// 滚动到结束
        /// </summary>
        public virtual void scrollToEnd() {
            m_pos = m_contentSize - m_pageSize;
            if (m_pos < 0) {
                m_pos = 0;
            }
            update();
            onScrolled();
        }

        /// <summary>
        /// 更新布局方法
        /// </summary>
        public override void update()
        {
            if (m_native != null && !m_native.m_lockUpdate)
            {
                if (m_pos > m_contentSize - m_pageSize)
                {
                    m_pos = m_contentSize - m_pageSize;
                }
                if (m_pos < 0)
                {
                    m_pos = 0;
                }
                base.update();
            }
        }
    }
}
